/**
 * this class handle de CRUD operations in mongo db for Administrators
 */
package co.edu.unal.satacredito.database.dao;

import co.edu.unal.satacredito.database.entity.Administrator;
import co.edu.unal.satacredito.database.entity.exceptions.NonexistentEntityException;
import co.edu.unal.satacredito.database.entity.exceptions.NullFieldEntityException;
import co.edu.unal.satacredito.database.entity.exceptions.PreexistingEntityException;
import com.google.code.morphia.Datastore;
import com.google.code.morphia.query.Query;
import com.google.code.morphia.query.UpdateOperations;
import java.util.List;
import org.bson.types.ObjectId;

/**
 *
 * @author Miguel Alexander Diaz 257835
 */
public class AdministratorMongoDao {

    private Datastore ds = null;

    public AdministratorMongoDao(Datastore ds) {
        this.ds = ds;
        this.ds.ensureIndexes();
    }

    public Datastore getDatastore() {
        return ds;
    }

    public void create(Administrator administrator) throws PreexistingEntityException {
        try {
            ds.save(administrator);
        } catch (Exception e) {
            throw new PreexistingEntityException("The administrator with name "
                    + administrator.getName() + "couldn't be created. Already exist.");
        }
    }

    public void update(ObjectId id, Administrator newadministrator) throws
            NonexistentEntityException, PreexistingEntityException, NullFieldEntityException, Exception {
        newadministrator.setId(id);
        try {
            Query q = ds.createQuery(Administrator.class).field("_id").equal(id);
            UpdateOperations<Administrator> ops = null;
            try {
                ops = ds.createUpdateOperations(Administrator.class).set("user", newadministrator.getUser()).set("document", newadministrator.getDocument()).set("name", newadministrator.getName()).set("lastName", newadministrator.getLastName()).set("user", newadministrator.getUser()).set("password", newadministrator.getPassword());
            } catch (Exception e) {
                throw new NullFieldEntityException("the Administrator with id '"
                        + id.toString() + "' have null fields.");
            }
            ds.update(q, ops);
        } catch (Exception e) {
            if (e.getClass().getSimpleName().equals("DuplicateKey")) {
                throw new PreexistingEntityException(e.getMessage());
            } else if (e.getClass().equals(NullFieldEntityException.class)) {
                throw e;
            } else {
                throw new NonexistentEntityException("The administrator with id '"
                        + id.toString() + "' couldn't be updated. May no longer exist");
            }
        }
    }

    public void delete(ObjectId id) throws NonexistentEntityException {
        try {
            Query q = ds.createQuery(Administrator.class).field("_id").equal(id);
            ds.delete(q);
        } catch (Exception e) {
            throw new NonexistentEntityException("The administrator with the id '"
                    + id.toString() + "' couldn't be deleted. May no longer exist.");
        }
    }

    public List<Administrator> findAll() throws NonexistentEntityException {
        try {
            List<Administrator> list = ds.find(Administrator.class).asList();
            return list;
        } catch (Exception e) {
            throw new NonexistentEntityException("The database "
                    + ds.getMongo().getUsedDatabases()
                    + " at " + ds.getMongo().getAddress()
                    + " don't contain any element of the 'Administrator' type ");
        }
    }

    public Administrator findByUser(String user) throws NonexistentEntityException, Exception {
        try {
            Query q = ds.createQuery(Administrator.class).field("user").equal(user);
            if (q.countAll()
                    == 0) {
                throw new NonexistentEntityException("The administrator with user '"
                        + user + "' couldn't be find. May no longer exist");
            } else {
                Administrator ad = (Administrator) q.get();
                return ad;
            }
        } catch (Exception e) {
            throw e;
        }
    }
}